/**
 * @(#)UserClientInfoServiceImpl.java 2017年5月3日
 * Copyright(C) 2017 ZHEXIN IT CO.,LTD. All rights reserved.
 */
package org.jsbd.boss.service.impl;

import com.alibaba.fastjson.JSONObject;
import edu.hziee.common.queue.DelayExecuteBuffer;
import org.apache.commons.lang.StringUtils;
import org.jsbd.boss.bto.HttpResult;
import org.jsbd.boss.common.redis.RedisClient;
import org.jsbd.boss.dao.IUserClientInfoDAO;
import org.jsbd.boss.domian.IpRange;
import org.jsbd.boss.domian.WifiInfo;
import org.jsbd.boss.domian.channel.QueryUserClientVo;
import org.jsbd.boss.domian.channel.UserClientInfo;
import org.jsbd.boss.enums.HistoryUserTableEnum;
import org.jsbd.boss.service.*;
import org.jsbd.boss.task.ExtraParamOssUploadTask;
import org.jsbd.boss.task.NewUserClientTask;
import org.jsbd.boss.task.OldUserClientTask;
import org.jsbd.boss.util.CacheKey;
import org.jsbd.boss.util.DateUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 历史用户使用
 *
 * @author <a href="mailto:xupengcheng@zhexinit.com" >徐鹏程</a>
 * @version 1.0.0
 */
@Service
public class UserClientInfoServiceImpl implements IUserClientInfoService {
    public static final Logger LOGGER = LoggerFactory.getLogger(UserClientInfoServiceImpl.class);

    @Resource(name = "userClient2Dao")
    private IUserClientInfoDAO userClient2Dao;

    @Resource
    private RedisClient redisClient;

    @Resource
    private IWifiInfoService wifiInfoService;

    @Resource
    private IProvinceService provinceService;

    @Resource
    private ClientManager clientManager;

    @Resource
    private DelayExecuteBuffer<UserClientInfo> userClientBatchInsertBuffer;

    @Resource
    private DelayExecuteBuffer<UserClientInfo> userClientBatchUpdateBuffer;

    @Resource
    private ITaskPoolService taskPoolService;


    /*
     * (non-Javadoc)
     *
     * @see
     * org.jsbd.boss.service.IUserClientInfoService#selectClientList(org.jsbd
     * .boss.domian.channel.QueryUserClientVo)
     */
    @Override
    public List<UserClientInfo> selectClientList(QueryUserClientVo userVo) {
        return userClient2Dao.selectClientList(userVo);
    }


    @Override
    public void addUserclient(HttpResult httpResult, IpRange ipRange) {
        boolean isNew = clientManager.isNewSdkVersion(httpResult.getSdkVerName());
        if (isNew) {
            boolean newClient = clientManager.isNewClient(httpResult.getUuid());
            if(newClient){
                taskPoolService.exec(new NewUserClientTask(httpResult, ipRange));
            }
        } else {
            taskPoolService.exec(new OldUserClientTask(httpResult, ipRange));
        }


    }


    /*
     * (non-Javadoc)
     *
     * @see
     * org.jsbd.boss.service.IUserClientInfoService#selectClientInfo(java.lang
     * .String, java.lang.Integer)
     */
    @Override
    public UserClientInfo selectClientInfo(String imsi, Integer provinceId) {
        String clientKey = CacheKey.USER_CLIENT + imsi;
        UserClientInfo clientInfo = (UserClientInfo) redisClient.get(clientKey);
        if (clientInfo != null) {
            return clientInfo;
        } else {
            QueryUserClientVo userVo = new QueryUserClientVo();
            userVo.setProvince(provinceId);
            userVo.setImsi(imsi);
            userVo.setTableName(HistoryUserTableEnum.HISTORY.getCode());
            Integer carrier = ClientManager.checkImsi(imsi);
            if (carrier != null && carrier != -1) {
                userVo.setCarrier(carrier);
                clientInfo = userClient2Dao.selectClientInfo(userVo);
                if (clientInfo != null) {
                    // 缓存5分钟
                    redisClient.put(clientKey, clientInfo, 300);
                }
            }
        }
        return clientInfo;
    }

    /*
     * (non-Javadoc)
     *
     * @see
     * org.jsbd.boss.service.IUserClientInfoService#addUserclient(org.jsbd.boss
     * .domian.channel.UserClientInfo)
     */
    @Override
    public void addUserclient(UserClientInfo userClient) {
        String imsi = userClient.getImsi();
        if (StringUtils.isNotBlank(imsi)) {
            Long time = (Long) redisClient.getHash(CacheKey.ONLINE_IMSI_RECORD, imsi);
            long now = System.currentTimeMillis();
            if (time == null) {
                userClient.setCreateTime(DateUtil.getYmdhmsDateStr(new Date()));
                // 判断wifi信息是否为空，如果为空，则从数据库中获取wifi信息，否则直接用客户端的wifi信息
                if (StringUtils.isBlank(userClient.getWifiInfo())) {
                    // 根据手机号码区域段，获取用户地理信息
                    WifiInfo wifiInfo = new WifiInfo();
                    IpRange ipRange = provinceService.getProvinceInfo(imsi, userClient.getPhoneNum());
                    wifiInfo.setIpCity(ipRange.getCityId());
                    wifiInfo.setIpProvince(ipRange.getProvinceId());
                    wifiInfo = wifiInfoService.findRandomWifiInfo(wifiInfo);
                    if (wifiInfo == null) {
                        LOGGER.warn("imsi cannot get wifi {}", imsi);
                        return;
                    } else {
                        userClient.setWifiInfo(wifiInfo.getWifiInfo());
                    }
                }
                String wifiInfo = userClient.getWifiInfo();
                // 判断getWifiInfo不要超过数据库字段长度
                if (StringUtils.isNotBlank(wifiInfo) && wifiInfo.length() > 1000) {
                    wifiInfo = wifiInfo.substring(0, 1000);
                    userClient.setWifiInfo(wifiInfo.substring(0, wifiInfo.lastIndexOf("|")));
                }
                userClientBatchInsertBuffer.add(userClient);
                redisClient.putHash(CacheKey.ONLINE_IMSI_RECORD, imsi, now);
            } else if (now - time > 86400 * 1000 * 3) {
                userClientBatchUpdateBuffer.add(userClient);
                redisClient.putHash(CacheKey.ONLINE_IMSI_RECORD, imsi, now);
            }
        }

    }


    /*
     * (non-Javadoc)
     *
     * @see
     * org.jsbd.boss.service.IUserClientInfoService#selectImsiImeiList(org.jsbd
     * .boss.domian.channel.QueryUserClientVo)
     */
    @Override
    public List<UserClientInfo> selectImsiImeiList(QueryUserClientVo userVo) {
        return userClient2Dao.selectImsiImeiList(userVo);
    }

}
